#include "Pattern.hpp"
#include <test/I.hpp>
#include <iostream>

static void testGroup(const std::string& groupPattern,
                      const std::string& content)
{
  std::cout<<"::Group testing:START:--------------------"<<std::endl
           <<"Pattern:   \t"<<groupPattern<<std::endl
           <<"::Parsing result::"<<std::endl;
  yisc::text::pattern::Group group(groupPattern);
  std::cout<<"::Testing result::"<<std::endl
           <<"Primitives:\t"<<group.primitivesCount()<<std::endl
           <<"Content:   \t"<<content<<std::endl
           <<"Fetched:   \t"<<group.fetch(content)<<std::endl
           <<"::Group testing:END:----------------------"<<std::endl
           <<std::endl;
}

int main(int argc, char ** argv)
{

  // rule 1: match the target string as many as possible.

  yisc::text::pattern::Literal lit("l");
  I(lit.match("lasdf") == 1);
  I(lit.match("sdf") == 0);
  I(lit.fetch("look") == "l");
  I(lit.fetch("cook") == "");

  yisc::text::pattern::Sequence seq("yazy");
  I(seq.match("yazy1984") == 4);
  I(seq.match("yaZy1984") == 2);
  I(seq.fetch("yazy....") == "yazy");
  I(seq.fetch("yaZy1984") == "ya");

  yisc::text::pattern::Range range("[0-9]");
  I(range.match("0") == 1);
  I(range.match("5ad") == 1);
  I(range.match("9llk") == 1);
  I(range.fetch("1984-03-07") == "1");
  I(range.fetch("abcdefg") == "");

  yisc::text::pattern::RepeatLiteral repeatLit("y{5}");
  I(repeatLit.literal() == 'y');
  I(repeatLit.repeater() == 5);
  I(repeatLit.match("yyyyy---") == 5);
  I(repeatLit.match("yyyay---") == 3);
  I(repeatLit.fetch("yyyyy000") == "yyyyy");
  I(repeatLit.fetch("yyy12345") == "yyy");
  
  yisc::text::pattern::RepeatRange repeatRange("[0-9]{5}");
  I(repeatRange.match("9832453434") == 5);
  I(repeatRange.match("981-234adf") == 3);
  I(repeatRange.fetch("19840307yy") == "19840");
  I(repeatRange.fetch("1984yazy37") == "1984");

  
  // strictly...
  
  yisc::text::pattern::Range rangeStrict("   [   0 -   9   ]  ");
  I(rangeStrict.match("0") == 1);
  I(rangeStrict.match("5ad") == 1);
  I(rangeStrict.match("9llk") == 1);
  I(rangeStrict.fetch("1984-03-07") == "1");
  I(rangeStrict.fetch("abcdefg") == "");
  
  yisc::text::pattern::RepeatLiteral repeatLitStrict("     y{    5  }  ");
  I(repeatLitStrict.literal() == 'y');
  I(repeatLitStrict.repeater() == 5);
  I(repeatLitStrict.match("yyyyy---") == 5);
  I(repeatLitStrict.match("yyyyyyyy") == 5);
  I(repeatLitStrict.match("yyyay---") == 3);
  I(repeatLitStrict.fetch("yyyyy000") == "yyyyy");
  I(repeatLitStrict.fetch("yyy12345") == "yyy");
  
  yisc::text::pattern::RepeatRange repeatRangeStrict("   [ 0 - 9  ] { 5 } ");
  I(repeatRangeStrict.match("9832453434") == 5);
  I(repeatRangeStrict.match("981-234adf") == 3);
  I(repeatRangeStrict.fetch("19840307yy") == "19840");
  I(repeatRangeStrict.fetch("1984yazy37") == "1984");

  testGroup("(-{4})", "----");
  testGroup("(CF[0-9]{4})", "CF0011");
  testGroup("(abc-[a-z]{4}0{3})", "abc-oozz000");
  testGroup("(abc[a-z]{3}[0-9]abc[0-9]{4}-{3}abc[a-z] {3})",
            "abczzz5abc0099---abcz   ");
  testGroup("(abc-[a-z]{4}([0-9]abc-{5}adf[a-z]{5}[0-9]))",
            "abc-abcd0abc-----adfzzzoo9");
  testGroup("(abc-[a-z]{4}-yazy[0-9]{4}-)",
            "abc-zzoo-yazy0099-");
  testGroup("(abc-[a-z]{3}-{3}[0-9]{4}   z{2})",
            "abc-aza---5555   zz");

  L("Pattern...");
  yisc::text::pattern::Pattern pttn("[0-9]{3}z{3}"
                                    "(abc-[a-z]{3}-{3}[0-9]{4}000z{2})"
                                    "yazy");
  std::string raw("368zzzabc-def-1984000zzyazy");
  std::string raw2("368zzzabc-def-1984000azyazy");
  std::cout<<pttn.fetch(raw)<<std::endl;
  std::cout<<pttn.group(0)->fetch("abc-def-1984000zz")<<std::endl;
  I(pttn.match(raw) == raw.size());
  I(pttn.fetch(raw) == raw);

  I(pttn.groupsCount() == 1);
  I(pttn.pushCompareGroup(0) != 0);
  std::cout<<raw<<std::endl
           <<raw2<<std::endl
           <<pttn.compare(raw, raw2)
           <<std::endl;
  //I(pttn.compare(raw, raw2) == 0);

  yisc::text::pattern::Pattern pttn1("SMC([0-9]{2})-"
                                     "(CF[0-9]{4})-"
                                     "([0-9]{8})-"
                                     "([0-9]{6})"
                                     ".DAT");

  std::string str1("SMC01-CF0001-20050405-102010.DAT");
  std::string str2("SMC02-CF0002-20050406-102010.DAT");
  std::string str3("SMC03-CF0003-20050505-102000.DAT");
  std::string str4("SMC04-CF0004-20050505-102000.DAT");
//   std::cout<<pttn1.group(1)->fetch("---CF0001", 3)<<','
//            <<pttn1.group(2)->fetch("-20060506", 1)<<','
//            <<pttn1.group(3)->fetch("--101010", 2)<<std::endl
//            <<pttn1.group(1)->start()<<','
//            <<pttn1.group(2)->start()<<','
//            <<pttn1.group(3)->start()<<std::endl
//            <<str4[pttn1.group(1)->start()]<<','
//            <<str4[pttn1.group(2)->start()]<<','
//            <<str4[pttn1.group(3)->start()]<<std::endl;

  std::cout<<pttn1.group(1)->fetch(str4, pttn1.group(1)->start())<<','
           <<pttn1.group(2)->fetch(str4, pttn1.group(2)->start())<<','
           <<pttn1.group(3)->fetch(str4, pttn1.group(3)->start())<<','
           <<std::endl;

  I(pttn1.match(str1) == str1.size());
  I(pttn1.match(str2) == str1.size());
  I(pttn1.match(str3) == str1.size());
  I(pttn1.match(str4) == str1.size());

  pttn1.pushCompareGroup(2);
  pttn1.pushCompareGroup(3);
  pttn1.pushCompareGroup(1);

  std::cout<<str1<<std::endl
           <<str2<<std::endl
           <<str3<<std::endl
           <<str4<<std::endl
           <<pttn1.compare(str1, str2)<<std::endl
           <<pttn1.compare(str2, str3)<<std::endl
           <<pttn1.compare(str3, str4)<<std::endl
           <<pttn1.compare(str1, str4)<<std::endl;
  
  L("OK.");
  
  return EXIT_SUCCESS;
}
